﻿package frEngine.core.mesh
{
    import baseEngine.basic.*;
    import baseEngine.core.*;
    import baseEngine.modifiers.*;
    import com.gengine.global.*;
    import flash.events.*;
    import flash.utils.*;
    import frEngine.*;
    import frEngine.animateControler.*;
    import frEngine.animateControler.keyframe.*;
    import frEngine.core.*;
    import frEngine.effectEditTool.manager.*;
    import frEngine.event.*;
    import frEngine.loaders.away3dMd5.*;
    import frEngine.loaders.resource.info.*;
    import frEngine.manager.*;
    import frEngine.pools.*;
    import frEngine.render.*;
    import frEngine.render.layer.*;
    import frEngine.shader.*;
    import frEngine.shader.filters.fragmentFilters.*;
    import frEngine.shader.filters.vertexFilters.*;

    public class Md5Mesh extends Mesh3D
    {
        private var _md5Controler:Md5SkinAnimateControler;
        public var initMeshCompleted:Boolean = false;
        private var _defaultPlayLable:String;
        protected var _animUrl:String;
        protected var _meshUrl:String;
        private var _skeletonInfo:SkeletonInfo;
        protected var _md5MeshInfo:Md5MeshInfo;
        public var openShadow:Boolean = true;

        public function Md5Mesh(param1:String)
        {
            super(param1, false, null);
            this.setMateiralBlendMode(EBlendType.BLEND_NONE);
            this.setLayer(Layer3DManager.modelLayer0, false);
            this.material.materialParams.colorKillvalue = 0;
            return;
        }// end function

        public function reinit(param1:String, param2:RenderList) : void
        {
            this.renderList = param2;
            if (param1)
            {
                this.meshUrl = param1;
            }
            return;
        }// end function

        public function clear() : void
        {
            this.targetMd5Controler.clear();
            this.targetMd5Controler.labels = new Dictionary(false);
            FrEventDispatcher.instance.proxyRemoveEventListener(this._md5MeshInfo, Engine3dEventName.PARSE_RESOURCE_FINISH, this.checkMeshComplete);
            FrEventDispatcher.instance.proxyRemoveEventListener(this._skeletonInfo, Engine3dEventName.PARSE_RESOURCE_FINISH, this.checkAnimateComplete);
            this._skeletonInfo = null;
            this._md5MeshInfo = null;
            this.meshUrl = null;
            this.animUrl = null;
            disposeSurfaces();
            this._md5Controler = null;
            return;
        }// end function

        public function get targetMd5Controler() : Md5SkinAnimateControler
        {
            if (!this._md5Controler)
            {
                this._md5Controler = this.getAnimateControlerInstance(AnimateControlerType.Md5SkinAnimateControler) as Md5SkinAnimateControler;
            }
            return this._md5Controler;
        }// end function

        public function get meshUrl() : String
        {
            return this._meshUrl;
        }// end function

        public function set meshUrl(param1:String) : void
        {
            if (this._meshUrl == param1)
            {
                return;
            }
            this.initMeshCompleted = false;
            if (this._meshUrl && this._meshUrl != param1)
            {
                Resource3dManager.instance.unLoad(this._meshUrl, this.loadMeshComplete);
            }
            this._meshUrl = param1;
            if (this._md5MeshInfo)
            {
                FrEventDispatcher.instance.proxyRemoveEventListener(this._md5MeshInfo, Engine3dEventName.PARSE_RESOURCE_FINISH, this.checkMeshComplete);
                this._md5MeshInfo = null;
            }
            if (param1)
            {
                Resource3dManager.instance.load(param1, this.loadMeshComplete, loadPriority);
            }
            return;
        }// end function

        override public function getAnimateControlerInstance(param1:int, param2:Modifier = null) : Modifier
        {
            var _loc_3:* = super.getAnimateControlerInstance(param1, param2);
            if (_loc_3 == null)
            {
                switch(param1)
                {
                    case AnimateControlerType.Md5SkinAnimateControler:
                    {
                        _loc_3 = param2 ? (param2) : (FrObjectPool.getObject(Md5SkinAnimateControler, this));
                        break;
                    }
                    default:
                    {
                        break;
                    }
                }
                if (_loc_3)
                {
                    _animateControlerList[param1] = _loc_3;
                    _loc_3.targetObject3d = this;
                }
            }
            return _loc_3;
        }// end function

        override public function draw(param1:Boolean = true, param2:ShaderBase = null) : void
        {
            var _loc_3:int = 0;
            if (!_scene)
            {
                return;
            }
            if (this.visible && !this.isHide)
            {
                render.draw(this, param2);
            }
            if (param1)
            {
                _loc_3 = children.length - 1;
                while (_loc_3 >= 0)
                {
                    
                    children[_loc_3].draw(true, param2);
                    _loc_3 = _loc_3 - 1;
                }
            }
            if (_eventFlags & EXIT_DRAW_FLAG)
            {
                FrEventDispatcher.instance.proxyDispatchEvent(this, Engine3dEventName.VISIBLE_CHANGE_EVENT);
            }
            return;
        }// end function

        public function initAnimate(param1:String, param2:String = null) : void
        {
            this._defaultPlayLable = param2;
            this.animUrl = param1;
            return;
        }// end function

        override public function drawShadow() : void
        {
            if (this.openShadow && _visible && this._animUrl)
            {
                this.targetMd5Controler.drawShadow(this);
            }
            return;
        }// end function

        public function get animUrl() : String
        {
            return this._animUrl;
        }// end function

        public function set animUrl(param1:String) : void
        {
            if (param1 && this._animUrl == param1)
            {
                return;
            }
            if (this._animUrl)
            {
                Resource3dManager.instance.unLoad(this._animUrl, this.loadAnimateComplete);
            }
            this._animUrl = param1;
            if (this._skeletonInfo)
            {
                FrEventDispatcher.instance.proxyRemoveEventListener(this._skeletonInfo, Engine3dEventName.PARSE_RESOURCE_FINISH, this.checkAnimateComplete);
            }
            this._skeletonInfo = null;
            this.targetMd5Controler.labels = new Dictionary(false);
            if (this._animUrl)
            {
                this.render = this.targetMd5Controler;
                Resource3dManager.instance.load(this._animUrl, this.loadAnimateComplete, loadPriority);
                var _loc_2:* = MD5MeshParserBase.maxJointCount;
                this._originalMaterial.materialParams.skinNum = MD5MeshParserBase.maxJointCount;
                this.material.materialParams.skinNum = _loc_2;
            }
            else
            {
                this.render = StaticMd5Render.instance;
                this.targetMd5Controler.addAnimateTracks(null, null);
                var _loc_2:int = 0;
                this._originalMaterial.materialParams.skinNum = 0;
                this.material.materialParams.skinNum = _loc_2;
            }
            return;
        }// end function

        public function loadAnimateComplete(param1:SkeletonInfo) : void
        {
            this._skeletonInfo = param1;
            if (param1.proceedParsed)
            {
                this.checkAnimateComplete();
            }
            else
            {
                FrEventDispatcher.instance.proxyAddEventListener(param1, Engine3dEventName.PARSE_RESOURCE_FINISH, this.checkAnimateComplete);
            }
            return;
        }// end function

        private function loadMeshComplete(param1:Md5MeshInfo) : void
        {
            this._md5MeshInfo = param1;
            if (param1.proceedParsed)
            {
                this.checkMeshComplete();
            }
            else
            {
                FrEventDispatcher.instance.proxyAddEventListener(param1, Engine3dEventName.PARSE_RESOURCE_FINISH, this.checkMeshComplete);
            }
            return;
        }// end function

        protected function checkMeshComplete(event:Event = null) : void
        {
            if (!this._md5MeshInfo || !this._md5MeshInfo.skeleton)
            {
                this.initMeshCompleted = false;
                return;
            }
            FrEventDispatcher.instance.proxyRemoveEventListener(this._md5MeshInfo, Engine3dEventName.PARSE_RESOURCE_FINISH, this.checkMeshComplete);
            addSurface(this._md5MeshInfo.surface3d);
            this.targetMd5Controler.skeleton = this._md5MeshInfo.skeleton;
            FrEventDispatcher.instance.proxyDispatchEvent(this, Engine3dEventName.PARSE_MESH_FINISH);
            this.initMeshCompleted = true;
            this.checkAnimateComplete();
            return;
        }// end function

        override public function dispose(param1:Boolean = true) : void
        {
            super.dispose(param1);
            this.openShadow = true;
            this.targetMd5Controler.removeAllFrameScript();
            material = _originalMaterial;
            this.alpha = 1;
            if (this.layer != Layer3DManager.modelLayer0)
            {
                this.setLayer(Layer3DManager.modelLayer0, false);
            }
            this.material.materialParams.depthWrite = true;
            this.material.materialParams.colorKillvalue = 0;
            this.setMateiralBlendMode(EBlendType.BLEND_NONE);
            this.targetMd5Controler.removeAllHang();
            this.targetMd5Controler.cuPlayLable = null;
            this.targetMd5Controler.curPlayTrackName = null;
            this.render = StaticMd5Render.instance;
            this.material.materialParams.skinNum = 0;
            this.clear();
            return;
        }// end function

        private function checkAnimateComplete(event:Event = null) : void
        {
            var _loc_2:SkeletonAnimator = null;
            if (!this._md5MeshInfo || !this._md5MeshInfo.proceedParsed)
            {
                return;
            }
            if (this._skeletonInfo && this._skeletonInfo.proceedParsed)
            {
                if (this._skeletonInfo.mainParser.headAndJoins.numJoints != this._md5MeshInfo.skeleton.numBones)
                {
                    if (Global.isDebugModle)
                    {
                        throw new Error("骨骼:" + this._skeletonInfo.name + "与模型:" + this._md5MeshInfo.name + "不相符");
                    }
                    return;
                }
                FrEventDispatcher.instance.proxyRemoveEventListener(this._md5MeshInfo, Engine3dEventName.PARSE_RESOURCE_FINISH, this.checkMeshComplete);
                FrEventDispatcher.instance.proxyRemoveEventListener(this._skeletonInfo, Engine3dEventName.PARSE_RESOURCE_FINISH, this.checkAnimateComplete);
                _loc_2 = new SkeletonAnimator(this._skeletonInfo);
                this.targetMd5Controler.addAnimateTracks(_loc_2, this._defaultPlayLable);
                this._skeletonInfo = null;
                this._md5MeshInfo = null;
                FrEventDispatcher.instance.proxyDispatchEvent(this, Engine3dEventName.InitComplete);
            }
            return;
        }// end function

        override public function setShaderBase(param1:VertexFilter, param2:FragmentFilter) : void
        {
            super.setShaderBase(new TransformFilter(), param2);
            return;
        }// end function

        override public function set maskEnable(param1:Boolean) : void
        {
            var _loc_2:Pivot3D = null;
            var _loc_3:Obj3dContainer = null;
            this.material.materialParams.enableMask = param1;
            for each (_loc_2 in this.children)
            {
                
                if (_loc_2 is Obj3dContainer)
                {
                    _loc_3 = Obj3dContainer(_loc_2);
                    _loc_3.updateMaskable(param1);
                }
            }
            return;
        }// end function

        public function get md5Controler() : Md5SkinAnimateControler
        {
            return this._md5Controler;
        }// end function

    }
}
